### Project 1 Attitude Sensing Unit Test for Gesture Glove———>MPU6050
***1.MPU6050***
The MPU6050 is a 6-axis motion processor (combining a 3-axis gyroscope and a 3-axis accelerometer) integrated on a single chip. It can detect both static and dynamic motion states, including angular velocity and acceleration. The module is equipped with **16-bit ADCs**, which simultaneously digitize data from all 6 axes, allowing the object's angular velocity and acceleration to be measured accurately.
It also contains a temperature sensor to monitor the chip's internal temperature during operation. Furthermore, it incorporates a **DMP (Digital Motion Processor)** to compute the object's orientation (such as Euler angles or Quaternions) by processing raw data from the gyroscope and accelerometer, reducing the computational load on the host controller.

***2.Circuit diagram***

| No. | Name | Description |
| ---- | ---- | ------------------------------------------------------------ |
| 1 | GND | Negative pole interface (0V) |
| 2 | VCC | Positive pole interface (compatible with 3.3V and 5V) |
| 3 | SDA | I2C Data Line. It connects to MCU to transmit data. |
| 4 | SCL | I2C Clock Line. It connects to MCU to synchronize data transmission. |
| 5 | XDA | I2C Data Line. It connects to external sensors to transmit data. |
| 6 | XCL | I2C Clock Line. It connects to external sensors to synchronize data transmission. |
| 7 | AD0 | I2C sub-address. The address is 0x69 when the board is at a high level, while the address is 0x68 when at low. |
| 8 | INT | An external interrupt pin. It detects MPU6050 internal interrupt time. |
- Operating voltage: 3.3V, 5V
- Static current: 5μA
- Rotating current: 3mA
- Maximum rotation speed: 2000°/s
- Acceleration scales: ±2g, ±4g, ±8g, ±16g
- Temperature range: –10°C ~ +65°C
***3.MPU6050 Data Acquisition***
***Note: Since both Bluetooth module communication and code uploads utilize the hardware serial port, you must disconnect the Bluetooth module before each code upload and reconnect it only after the upload completes. If the course does not require Bluetooth functionality, you may choose to leave the Bluetooth module disconnected.***
Experiment 1 (Acquiring Raw MPU6050 Values)
```c
#include
MPU6050lib mpu;
int16_t accelCount[3]; // Store 16-bit signed output of acclerometer
int16_t gyroCount[3]; // Store 16-bit signed output of gyroscope
int16_t tempCount; // Store the real internal chip temperature in degrees Celsius
float gyroBias[3] = {0, 0, 0}; // Correct gyroscope and acclerometer bias
float accelBias[3] = {0, 0, 0};
float SelfTest[6]; // Self-test value storing container
void setup()
{
Wire.begin();
Serial.begin(9600);
// Read the WHO_AM_I register, this is a good test of communication
// Read WHO_AM_I register for MPU-6050
uint8_t c = mpu.readByte(MPU6050_ADDRESS, WHO_AM_I_MPU6050);
Serial.print("I AM ");
Serial.print(c, HEX);
//Set the minimum scale if the device is in self-test
// Possible gyro scales (and their register bit settings) are:
// 250 DPS (0x00), 500 DPS (0x01), 1000 DPS (0x10), and 2000 DPS (0x11).
// Possible accelerometer scales (and their register bit settings) are:
// 2 Gs (0x00), 4 Gs (0x01), 8 Gs (0x10), and 16 Gs (0x11).
mpu.settings(AFS_8G, GFS_250DPS);
// version WHO_AM_I should always be 0x68 //MPU6050 address 1: 0x68, address 2: 0x98
if (c == 0x68 || c == 0x98)
{
Serial.println("MPU6050 is online...");
// Start by performing self test
mpu.MPU6050SelfTest(SelfTest);
if (SelfTest[0] < 1.0f && SelfTest[1] < 1.0f && SelfTest[2] < 1.0f && SelfTest[3] < 1.0f && SelfTest[4] < 1.0f
&& SelfTest[5] < 1.0f)
{
Serial.println("Pass Selftest!");
// Calibrate gyro and accelerometers, load biases in bias registers
mpu.calibrateMPU6050(gyroBias, accelBias);
mpu.settings(AFS_2G, GFS_250DPS);
mpu.initMPU6050();
// Initialize device for active mode read of acclerometer, gyroscope, and temperature
Serial.println("MPU6050 initialized for active data mode....");
}
else
{
Serial.print("Could not connect to MPU6050: 0x");
Serial.println(c, HEX);
// Loop forever if communication doesn't happen
while (1) ;
}
}
}
void loop()
{
// If data ready bit set, all data registers have new data
// check if data ready interrupt
if (mpu.readByte(MPU6050_ADDRESS, INT_STATUS) & 0x01)
{
// Read the x/y/z adc values
mpu.readAccelData(accelCount);
// Read the x/y/z adc values
mpu.readGyroData(gyroCount);
Serial.println("--------");
Serial.print("Accel X:");
Serial.println(accelCount[0]);
Serial.print("Accel Y:");
Serial.println(accelCount[1]);
Serial.print("Accel Z:");
Serial.println(accelCount[2]);
Serial.println("--------");
Serial.print("Gyro X:");
Serial.println(gyroCount[0]);
Serial.print("Gyro Y:");
Serial.println(gyroCount[1]);
Serial.print("Gyro Z:");
Serial.println(gyroCount[2]);
Serial.println("--------");
// Read the x/y/z adc values
tempCount = mpu.readTempData();
// Temperature in degrees Centigrade
Serial.print("Initial TEMP values:");
Serial.println(tempCount);
Serial.println("--------");
delay(500);
}
}
```
Place the expansion board smoothly, press and hold the reset button. The more balanced the MPU6050 is, the more accurate the data it acquired will be.
When you open the serial monitor, you will see three repeated data blocks, with the following meanings:

**Accel X, Accel Y, Accel Z**
- **Meaning:** Represents **Linear Acceleration** (including gravity) detected along the X, Y, and Z axes.
- **Unit:** Raw LSB (Least Significant Bit) counts.
- **Note:** Since `AFS_2G` is set in your setup, a value of approx **16,384** equals **1 g** (gravity). If the sensor is flat on a table, Z should be near 16,384 (or -16,384 depending on orientation), while X and Y should be near 0.
**Gyro X, Gyro Y, Gyro Z**
- **Meaning:** Represents **Angular Velocity** (Rotational Speed). It measures how fast the sensor is rotating *around* the X, Y, and Z axes.
- **Unit:** Raw LSB counts.
- **Note:** Since GFS_250DPS is set, a value of **131** equals **1 degree per second**. If the sensor is stationary, these values should be very close to 0.
**Initial TEMP values**
- **Meaning:** Represents the **Internal Die Temperature** of the MPU6050 chip.
- **Unit:** Raw LSB counts.
- **Note:** This is *not* degrees Celsius yet. You must apply a formula to convert it (usually: $\text{Temp}_{C} = \frac{\text{RawValue}}{340.0} + 36.53$).
Experiment 2 (MPU6050 Temperature Acquisition and Conversion)
```c
#include
MPU6050lib mpu;
int16_t tempCount; // Store the real internal chip temperature in degrees Celsius
float temperature; // Store the actual temperature in degrees Celsius
float gyroBias[3] = {0, 0, 0}; // Correct gyroscope and acclerometer bias
float accelBias[3] = {0, 0, 0};
float SelfTest[6]; // Self-test value storing container
void setup()
{
Wire.begin();
Serial.begin(9600);
// Read the WHO_AM_I register, this is a good test of communication
// Read WHO_AM_I register for MPU-6050
uint8_t c = mpu.readByte(MPU6050_ADDRESS, WHO_AM_I_MPU6050);
Serial.print("I AM ");
Serial.print(c, HEX);
//Set the minimum scale if the device is in self-test
// Possible gyro scales (and their register bit settings) are:
// 250 DPS (0x00), 500 DPS (0x01), 1000 DPS (0x10), and 2000 DPS (0x11).
// Possible accelerometer scales (and their register bit settings) are:
// 2 Gs (0x00), 4 Gs (0x01), 8 Gs (0x10), and 16 Gs (0x11).
mpu.settings(AFS_8G, GFS_250DPS);
// version WHO_AM_I should always be 0x68 //MPU6050 address 1: 0x68, address 2: 0x98
if (c == 0x68 || c == 0x98) {
Serial.println("MPU6050 is online...");
// Start by performing self test
mpu.MPU6050SelfTest(SelfTest);
if (SelfTest[0] < 1.0f && SelfTest[1] < 1.0f && SelfTest[2] < 1.0f && SelfTest[3] < 1.0f && SelfTest[4] < 1.0f
&& SelfTest[5] < 1.0f)
{
Serial.println("Pass Selftest!");
// Calibrate gyro and accelerometers, load biases in bias registers
mpu.calibrateMPU6050(gyroBias, accelBias);
mpu.settings(AFS_2G, GFS_250DPS);
mpu.initMPU6050();
// Initialize device for active mode read of acclerometer, gyroscope, and temperature
Serial.println("MPU6050 initialized for active data mode....");
}
else{
Serial.print("Could not connect to MPU6050: 0x");
Serial.println(c, HEX);
// Loop forever if communication doesn't happen
while (1) ;
}
}
}
void loop()
{
// If data ready bit set, all data registers have new data
// check if data ready interrupt
if (mpu.readByte(MPU6050_ADDRESS, INT_STATUS) & 0x01)
{
tempCount = mpu.readTempData(); // Read the x/y/z adc values
temperature = ((float) tempCount) / 340. + 36.53; // Temperature in degrees Centigrade
}
Serial.println("--------");
// Temperature in degrees Centigrade
Serial.print("TEMP values:");
Serial.println(temperature);
Serial.println("--------");
delay(500);
}
```

***Output Data Explanation***
This code specifically measures the **Internal Temperature** of the MPU6050 chip and converts it into a human-readable format.
- **TEMP values: [Number]**
- **Meaning:** This represents the actual temperature of the sensor chip in **Degrees Celsius (°C)**.
- **Difference from previous code:** In the previous code, you saw a raw integer (e.g., `1600`). In *this* code, the line `temperature = ((float) tempCount) / 340. + 36.53;` converts that raw number into a real temperature (e.g., `26.50`).
- **Note:** This is the temperature of the *silicon die* inside the chip, not necessarily the exact room air temperature (though it is usually close).